home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 3: CDPD 3 / Almathera Ten on Ten - Disc 3: CDPD3.iso / fish / 676-700 / 699 / iffconvert / src / iffpack.c < prev    next >
C/C++ Source or Header  |  1995-03-18  |  18KB  |  646 lines

  1. /**************************************************************************
  2. *                                                                         *
  3. *   iffpack                                                               *
  4. *                                                                         *
  5. *   Routines for loading and saving pictures with windows                 *
  6. *   using the old formats and the new compression format                  *
  7. *                                                                         *
  8. **************************************************************************/
  9. #include <intuition/intuition.h>
  10. #include <functions.h>
  11. #include <stdio.h>
  12.  
  13. #define NOERRORTEXT
  14. #include "iffpack.h"
  15.  
  16. #define BADFLAGS (SPRITES|VP_HIDE|GENLOCK_AUDIO|GENLOCK_VIDEO)
  17. #define FLAGMASK (~BADFLAGS)
  18. #define CAMGMASK (FLAGMASK & 0xffffL)
  19.  
  20. struct BMHD {
  21.    ULONG  Size;
  22.    USHORT Width,Height;
  23.    SHORT  LeftEdge,TopEdge;
  24.    UBYTE  Depth;
  25.    UBYTE  Mask;
  26.    UBYTE  Compression;
  27.    UBYTE  Pad;
  28.    USHORT Transparent;
  29.    UBYTE  XAspect,YAspect;
  30.    SHORT  ScrWidth,ScrHeight;
  31. };
  32.  
  33. static USHORT buf[256];
  34. static short count,runlen,ptr;
  35.  
  36. static short rows,bytes,depth;
  37. static cmode;
  38.  
  39. static short TempY=0,TempX=0;
  40. static struct BitMap MyBm;
  41. static struct RastPort MyRast;
  42. static short anzcolors;
  43. static USHORT colors[32];
  44.  
  45. /**************************************************************************
  46. *                                                                         *
  47. *  SetColors(vp):                                                         *
  48. *                                                                         *
  49. *  Set the colors, that were previously loaded with ReadPicSize           *
  50. *                                                                         *
  51. *  vp: Viewport of the Screen                                             *
  52. *                                                                         *
  53. **************************************************************************/
  54. SetColors(vp)
  55. struct ViewPort *vp;
  56. {
  57.    LoadRGB4(vp,colors,(long)anzcolors);
  58. }
  59.  
  60. /**************************************************************************
  61. *                                                                         *
  62. *  ReadPicSize(fp,winx,winy,srcx,srcy,depth,vmode                         *
  63. *                                                                         *
  64. *  Read the size and viewmode of the picture and load the colors to an    *
  65. *  internal buffer                                                        *
  66. *                                                                         *
  67. *  fp:        FILE-Pointer of stdio                                       *
  68. *  winx,winy: references to the size of the window                        *
  69. *  srcx,srcy: references to the size of the screen                        *
  70. *  depth:     reference to the depth of the screen                        *
  71. *  vmode:     reference to Viewmode                                       *
  72. *                                                                         *
  73. *  ReadPicSize sets the values of the referenced parameters               *
  74. *                                                                         *
  75. *  the result of ReadPicSize is 0 if no error occured or an error-code    *
  76. *  defined in iffpack.h                                                   *
  77. *                                                                         *
  78. **************************************************************************/
  79.  
  80. ReadPicSize(fp,winx,winy,scrx,scry,depth,vmode)
  81. FILE *fp;
  82. SHORT *winx,*winy;
  83. SHORT *scrx,*scry;
  84. SHORT *depth;
  85. USHORT *vmode;
  86. {
  87.    struct BMHD bmhd;
  88.    int err;
  89.    if(err=ReadHeader(fp,&bmhd,vmode)) return(err);
  90.    *winx=bmhd.Width;
  91.    *winy=bmhd.Height;
  92.    *scrx=bmhd.ScrWidth;
  93.    *scry=bmhd.ScrHeight;
  94.    *depth=bmhd.Depth;
  95.    return(0);
  96. }
  97.  
  98. /**************************************************************************
  99. *                                                                         *
  100. *  ReadBody: read the bitmap data to a rastport                           *
  101. *                                                                         *
  102. *  rp: pointer to rastport                                                *
  103. *                                                                         *
  104. *  fp: FILE-Pointer of stdio                                              *
  105. *                                                                         *
  106. **************************************************************************/
  107.  
  108. ReadBody(rp,fp)
  109. struct RastPort *rp;
  110. FILE *fp;
  111. {
  112.    long size;
  113.    short x,y,p;
  114.    int c;
  115.  
  116.    if(!fread(&size,4,1,fp)) return(BAD_IFF);
  117.  
  118.    if(cmode==0) {  /* Compression mode 0: no compression */
  119.       for(y=0;y<rows;y++) {
  120.          for(p=0;p<depth;p++) {
  121.             for(x=0;x<bytes;x++) {
  122.                if((c=getc(fp))==EOF) return(BAD_IFF);
  123.                MyBm.Planes[p][x]=c;
  124.             }
  125.          }
  126.          ClipBlit(&MyRast,0L,0L,rp,0L,(long)y,(long)TempX,1L,192L);
  127.          WaitBlit();
  128.       }
  129.    } else if(cmode==1) {  /* Compression mode 1: normal compression */
  130.       for(y=0;y<rows;y++) {
  131.          for(p=0;p<depth;p++) {
  132.             for(x=0;x<bytes;x++) {
  133.                if((c=compget(fp))==EOF) return(BAD_IFF);
  134.                if(c<256) {
  135.                   MyBm.Planes[p][x]=c;
  136.                }
  137.             }
  138.          }
  139.          ClipBlit(&MyRast,0L,0L,rp,0L,(long)y,(long)TempX,1L,192L);
  140.          WaitBlit();
  141.       }
  142.    } else if(cmode==2) { /* Compression mode 2: new compression */
  143.       for(x=0;x<bytes;x++) {
  144.          for(p=0;p<depth;p++) {
  145.             for(y=0;y<rows;y++) {
  146.                if((c=compget(fp))==EOF) return(BAD_IFF);
  147.                if(c<256) {
  148.                   MyBm.Planes[p][y<<1]=c;
  149.                }
  150.             }
  151.          }
  152.          ClipBlit(&MyRast,0L,0L,rp,(long)(x<<3),0L,8L,(long)TempY,192L);
  153.          WaitBlit();
  154.       }
  155.    }
  156.    IFFCleanup();
  157.    return(0);
  158. }
  159.  
  160. /**************************************************************************
  161. *                                                                         *
  162. *  WriteWindow(fp,w,mode):                                                *
  163. *                                                                         *
  164. *  Write the window win to the file with FILE-Pointer fp using the        *
  165. *  compression method mode                                                *
  166. *                                                                         *
  167. **************************************************************************/
  168.  
  169. WriteWindow(fp,w,mode)
  170. FILE *fp;
  171. struct Window *w;
  172. short mode;
  173. {
  174.    if(mode<0 || mode>2) return(UNKNOWN_COMPRESSION);
  175.    if(WriteBMHD(w,fp,mode)) return(WRITE_ERROR);
  176.    if(WriteCMAP(w->WScreen,fp)) return(WRITE_ERROR);
  177.    if(WriteCAMG(w->WScreen,fp)) return(WRITE_ERROR);
  178.    if(initcomp((short)w->Width,(short)w->Height,(short)w->WScreen->BitMap.Depth,
  179.           mode)) return(NO_MEMORY);
  180.    if(WriteBODY(w,fp,mode)) return(WRITE_ERROR);
  181.    IFFCleanup();
  182.    return(0);
  183. }
  184.  
  185. /**************************************************************************
  186. *                                                                         *
  187. *  IFF-Cleanup: frees all allocated memory                                *
  188. *                                                                         *
  189. **************************************************************************/
  190.  
  191. IFFCleanup()
  192. {
  193.    short a;
  194.    if(TempX) {
  195.       for(a=0;a<8;a++) {
  196.          if(MyBm.Planes[a])
  197.                  FreeRaster(MyBm.Planes[a],(long)TempX,(long)TempY);
  198.       }
  199.    }
  200.    TempX=TempY=0;
  201. }
  202.  
  203.  
  204. /***********************************
  205. *                                  *
  206. *  internal functions:             *
  207. *                                  *
  208. ***********************************/
  209.  
  210. /*  ReadHeader: read size-information, viewmode and colors  */
  211.  
  212. static ReadHeader(fp,bmhd,viewmode)
  213. FILE *fp;
  214. struct BMHD *bmhd;
  215. USHORT *viewmode;
  216. {
  217.    short status=0;
  218.    long id[3],sid,size;
  219.    if(!fread(id,12,1,fp)) return(BAD_IFF);
  220.    if(id[0]!='FORM') return(BAD_IFF);
  221.    if(id[2]!='ILBM') return(BAD_IFF);
  222.    *viewmode=0;
  223.    do {
  224.       if(!fread(&sid,4,1,fp)) return(BAD_IFF);
  225.       if(sid=='CMAP') {
  226.          if(status&1) return(BAD_IFF); /* doppelt */
  227.          if(ReadCMAP(fp)) return(BAD_IFF);
  228.          status|=1;
  229.       } else if(sid=='CAMG') {
  230.          if(status&2) return(BAD_IFF); /* doppelt */
  231.          if(ReadCAMG(fp,viewmode)) return(BAD_IFF);
  232.          status|=2;
  233.       } else if(sid=='BMHD') {
  234.          if(status&4) return(BAD_IFF); /* doppelt */
  235.          if(ReadBMHD(fp,bmhd,viewmode)) return(BAD_IFF);
  236.          status|=4;
  237.       } else if(sid!='BODY') {
  238.          if(!fread(&size,4,1,fp)) return(BAD_IFF);
  239.          size+=size&1;
  240.          if(fseek(fp,size,1)) return(BAD_IFF);
  241.       }
  242.    } while(sid!='BODY');
  243.    if(!(status&1) || !(status&4)) return(BAD_IFF); /* Daten fehlen */
  244.    if(initcomp((short)bmhd->Width,(short)bmhd->Height,(short)bmhd->Depth,
  245.             (short)bmhd->Compression)) return(NO_MEMORY);
  246.    rows=bmhd->Height;
  247.    bytes=((bmhd->Width+15)>>3)&0xfffe;
  248.    depth=bmhd->Depth;
  249.    cmode=bmhd->Compression;
  250.    if(cmode<0 || cmode>2) return(UNKNOWN_COMPRESSION);
  251.    return(0);
  252. }
  253.  
  254. /* Read chunk BMHD */
  255.  
  256. static ReadBMHD(fp,bmhd,vmode)
  257. FILE *fp;
  258. struct BMHD *bmhd;
  259. USHORT *vmode;
  260. {
  261.    if(!fread(bmhd,sizeof(struct BMHD),1,fp)) return(BAD_IFF);
  262.    if(bmhd->Size!=20) return(BAD_IFF);
  263.    *vmode=0;
  264.    if(bmhd->Width>400 && bmhd->Depth<=4) *vmode|=HIRES;
  265.    if(bmhd->Height>300) *vmode|=LACE;
  266.    if(bmhd->Depth>6) *vmode|=HAM;
  267.    return(0);
  268. }
  269.  
  270. /* read colormap */
  271.  
  272. static ReadCMAP(fp)
  273. FILE *fp;
  274. {
  275.    long size;
  276.    short a;
  277.    int r,g,b;
  278.    if(!fread(&size,4,1,fp)) return(1);
  279.    if(size % 3) return(1);
  280.    size/=3;
  281.    anzcolors=size;
  282.    for(a=0;a<size;a++) {
  283.       if((r=getc(fp))==EOF) return(1);
  284.       if((g=getc(fp))==EOF) return(1);
  285.       if((b=getc(fp))==EOF) return(1);
  286.       r&=0xf0;
  287.       g&=0xf0;
  288.       b&=0xf0;
  289.       colors[a]=(r<<4)|g|(b>>4);
  290.    }
  291.    return(0);
  292. }
  293.  
  294. /* read viewmode */
  295.  
  296. static ReadCAMG(fp,vmode)
  297. FILE *fp;
  298. USHORT *vmode;
  299. {
  300.    long a;
  301.    long size;
  302.    if(!fread(&size,4,1,fp)) return(1);
  303.    if(size!=4) return(1);
  304.    if(!fread(&a,4,1,fp)) return(1);
  305.    *vmode=a&CAMGMASK;
  306.    return(0);
  307. }
  308.  
  309. /*  write BMHD */
  310.  
  311. static WriteBMHD(w,fp,mode)
  312. struct Window *w;
  313. FILE *fp;
  314. short mode;
  315. {
  316.    struct BMHD bm;
  317.    if(!fwrite("FORM    ILBMBMHD",16,1,fp)) return(1);
  318.    bm.Size=20;
  319.    bm.Width=w->Width;
  320.    bm.Height=w->Height;
  321.    bm.ScrWidth=w->WScreen->Width;
  322.    bm.ScrHeight=w->WScreen->Height;
  323.    bm.LeftEdge=bm.TopEdge=0;
  324.    bm.Depth=w->WScreen->BitMap.Depth;
  325.    bm.Mask=bm.Pad=0;
  326.    bm.Compression=mode;
  327.    bm.Transparent=0;
  328.    bm.YAspect=11;
  329.    bm.XAspect=10;
  330.    if((w->WScreen->ViewPort.Modes&LACE) && !(w->WScreen->ViewPort.Modes&HIRES)) bm.XAspect=20;
  331.    if(!(w->WScreen->ViewPort.Modes&LACE) && (w->WScreen->ViewPort.Modes&HIRES)) bm.XAspect=5;
  332.    if(!fwrite(&bm,sizeof(struct BMHD),1,fp)) return(1);
  333.    return(0);
  334. }
  335.  
  336. /* write colormap */
  337.  
  338. static WriteCMAP(s,fp)
  339. struct Screen *s;
  340. FILE *fp;
  341. {
  342.    long size;
  343.    short anz,col;
  344.    short i;
  345.    int c;
  346.  
  347.    if(!fwrite("CMAP",4,1,fp)) return(1);
  348.    anz=s->BitMap.Depth;
  349.    anz=1<<anz;
  350.    if(anz>32) anz=32;
  351.    size=3*anz;
  352.    if(!fwrite(&size,4,1,fp)) return(1);
  353.  
  354.    for(i=0;i<anz;i++) {
  355.       col=GetRGB4(s->ViewPort.ColorMap,(long)i);
  356.       c=((col>>8)&0xf)<<4;
  357.       if(putc(c,fp)==EOF) return(1);
  358.       c=((col>>4)&0xf)<<4;
  359.       if(putc(c,fp)==EOF) return(1);
  360.       c=(col&0xf)<<4;
  361.       if(putc(c,fp)==EOF) return(1);
  362.    }
  363.    return(0);
  364. }
  365.  
  366. /* write viewmode */
  367.  
  368. static WriteCAMG(s,fp)
  369. struct Screen *s;
  370. FILE *fp;
  371. {
  372.    long a;
  373.    if(!fwrite("CAMG",4,1,fp)) return(1);
  374.    a=4;
  375.    if(!fwrite(&a,4,1,fp)) return(1);
  376.    a=s->ViewPort.Modes;
  377.    a&=CAMGMASK;
  378.    if(!fwrite(&a,4,1,fp)) return(1);
  379.    return(0);
  380. }
  381.  
  382. /* write bitmaps */
  383.  
  384. static WriteBODY(w,fp,mode)
  385. struct Window *w;
  386. FILE *fp;
  387. short mode;
  388. {
  389.    struct RastPort *rp;
  390.    struct BitMap *bm;
  391.    short bytes,rows;
  392.    long pos;
  393.    long size,bodysize,depth;
  394.    short x,y,p;
  395.  
  396.    UBYTE *plane;
  397.  
  398.    rp=w->RPort;
  399.  
  400.    if(!fwrite("BODY    ",8,1,fp)) return(1);
  401.    pos=ftell(fp);
  402.  
  403.    bm=MyRast.BitMap;
  404.  
  405.    bytes=((w->Width+15)>>3) & 0xfffe;
  406.    rows=w->Height;
  407.    depth=bm->Depth;
  408.  
  409.    if(mode==2) {
  410.       for(x=0;x<bytes;x++) {
  411.          if(x) {
  412.             ClipBlit(rp,(x-1L)<<3L,0L,&MyRast,0L,0L,16L,(long)TempY,192L);
  413.             WaitBlit();
  414.          } else {
  415.             ClipBlit(rp,0L,0L,&MyRast,8L,0L,8L,(long)TempY,192L);
  416.             WaitBlit();
  417.          }
  418.          for(p=0;p<depth;p++) {
  419.             if(comprow(fp,rows,x,p)) return(1);
  420.          }
  421.       }
  422.    } else if(mode==1) {
  423.       for(y=0;y<rows;y++) {
  424.          if(y) {
  425.             ClipBlit(rp,0L,(long)y-1L,&MyRast,0L,0L,(long)TempX,2L,192L);
  426.             WaitBlit();
  427.          } else {
  428.             ClipBlit(rp,0L,0L,&MyRast,0L,1L,(long)TempX,1L,192L);
  429.             WaitBlit();
  430.          }
  431.          for(p=0;p<depth;p++) {
  432.             if(compline(fp,bytes,y,p)) return(1);
  433.          }
  434.       }
  435.    } else {
  436.       for(y=0;y<rows;y++) {
  437.          ClipBlit(rp,0L,(long)y,&MyRast,0L,0L,(long)TempX,1L,192L);
  438.          WaitBlit();
  439.          for(p=0;p<depth;p++) {
  440.             plane=MyBm.Planes[p];
  441.             for(x=0;x<bytes;x++) {
  442.                if(putc((int)(plane[x]),fp)==EOF) return(1);
  443.             }
  444.          }
  445.       }
  446.    }
  447.  
  448.    size=ftell(fp);
  449.    bodysize=size-pos;
  450.    if(fseek(fp,pos-4L,0)) return(1);
  451.    if(!fwrite(&bodysize,4,1,fp)) return(1);
  452.    if(fseek(fp,4L,0)) return(1);
  453.    size-=8;
  454.    if(!fwrite(&size,4,1,fp)) return(1);
  455.    return(0);
  456. }
  457.  
  458. /* compress one line */
  459.  
  460. static compline(fp,bytes,y,p)
  461. FILE *fp;
  462. short bytes;
  463. short y,p;
  464. {
  465.    short x,x2,x3,lx;
  466.    short found;
  467.    short a;
  468.    UBYTE * ptr;
  469.    UBYTE *lptr;
  470.  
  471.    ptr=&MyBm.Planes[p][bytes];
  472.    lptr=MyBm.Planes[p];
  473.    lx=0;
  474.    for(x=0;x<bytes;x++) {
  475.       x2=x;
  476.       found=0;  /* count bytes with equal value */
  477.       while(ptr[x2]==ptr[x2+1] && x2<bytes-1 && x2-x<127) x2++;
  478.       x2++;
  479.       if((x-lx)==0 && x2-x>=2 || x2-x>=3) {
  480.          if(x-lx) {
  481.             /* save uncompressed bytes */
  482.             if(putc((int)(x-lx-1),fp)==EOF) return(1);
  483.             for(a=lx;a<x;a++) if(putc((int)ptr[a],fp)==EOF) return(1);
  484.          }
  485.          /* save compressed bytes */
  486.          if(putc(x-x2+1,fp)==EOF) return(1);
  487.          if(putc((int)ptr[x],fp)==EOF) return(1);
  488.          x=x2-1;
  489.          found=1;
  490.       }
  491.       if(found) {
  492.          lx=x+1;
  493.       } else {
  494.          if(x-lx==127) {
  495.             /* save uncompressed bytes */
  496.             if(fputc(127,fp)==EOF) return(1);
  497.             for(a=lx;a<=x;a++) if(putc(ptr[a],fp)==EOF) return(1);
  498.             lx=x+1;
  499.          }
  500.       }
  501.    }
  502.    if(lx<bytes) {
  503.       if(putc(bytes-lx-1,fp)==EOF) return(1);
  504.       for(a=lx;a<bytes;a++) if(putc((int)ptr[a],fp)==EOF) return(1);
  505.    }
  506.    return(0);
  507. }
  508.  
  509. /* compress one column (width: 8 bit) */
  510.  
  511. static comprow(fp,rows,x,p)
  512. FILE *fp;
  513. short rows;
  514. short x,p;
  515. {
  516.    short y,y2,y3,ly;
  517.    short found;
  518.    short a;
  519.    UBYTE * ptr;
  520.  
  521.    ptr=MyBm.Planes[p];
  522.    ly=0;
  523.    for(y=0;y<rows;y++) {
  524.       y3=y2=y;
  525.       found=0;   /* count bytes with equal value */
  526.       while(ptr[(y2<<1)+1]==ptr[(y2<<1)+3] && y2<rows-1 &&
  527.                                                     y2-y<127) y2++;
  528.       y2++;
  529.       if(x) {
  530.          /* compare with previous column */
  531.          while(ptr[y3<<1]==ptr[(y3<<1)+1] && y3<rows &&
  532.                                                     y3-y<256) y3++;
  533.       }
  534.       if(y2>=y3) {
  535.          if(y-ly==0 && y2-y>=2 || y2-y>=3) {
  536.             if(y-ly) {
  537.                /* write uncompressed data */
  538.                if(putc(y-ly-1,fp)==EOF) return(1);
  539.                for(a=ly;a<y;a++)
  540.                   if(putc((int)ptr[(a<<1)+1],fp)==EOF) return(1);
  541.             }
  542.             /* write compressed data: Byte-Run */
  543.             if(putc(y-y2+1,fp)==EOF) return(1);
  544.             if(putc((int)ptr[(y<<1)+1],fp)==EOF) return(1);
  545.             y=y2-1;
  546.             found=1;
  547.          }
  548.       } else {
  549.          if(!y-ly && y3-y>=2 || y3-y>=3) {
  550.             if(y-ly) {
  551.                /* write uncompressed data */
  552.                if(putc(y-ly-1,fp)==EOF) return(1);
  553.                for(a=ly;a<y;a++)
  554.                   if(putc((int)ptr[(a<<1)+1],fp)==EOF) return(1);
  555.             }
  556.             /* write compressed data: copy previous column */
  557.             if(putc(128,fp)==EOF) return(1);
  558.             if(putc(y3-y-1,fp)==EOF) return(1);
  559.             y=y3-1;
  560.             found=1;
  561.          }
  562.       }
  563.       if(found) {
  564.          ly=y+1;
  565.       } else {
  566.          if(y-ly==127) {
  567.             /* write uncompressed data */
  568.             if(fputc(127,fp)==EOF) return(1);
  569.             for(a=ly;a<=y;a++)
  570.                   if(putc(ptr[(a<<1)+1],fp)==EOF) return(1);
  571.             ly=y+1;
  572.          }
  573.       }
  574.    }
  575.    if(ly<rows) {
  576.       if(putc(rows-ly-1,fp)==EOF) return(1);
  577.       for(a=ly;a<rows;a++)
  578.          if(putc((int)ptr[(a<<1)+1],fp)==EOF) return(1);
  579.    }
  580.    return(0);
  581. }
  582.  
  583. /* init compression */
  584.  
  585. static initcomp(width,height,depth,mode)
  586. short width,height,depth,mode;
  587. {
  588.    short a;
  589.    if(TempX) IFFCleanup();
  590.    if(mode!=2) {
  591.       TempX=width;
  592.       TempY=2;
  593.       InitRastPort(&MyRast);
  594.       InitBitMap(&MyBm,(long)depth,(long)width,2L);
  595.       for(a=0;a<8;a++) MyBm.Planes[a]=0;
  596.       for(a=0;a<depth;a++) {
  597.          if(!(MyBm.Planes[a]=AllocRaster((long)width,2L))) return(NO_MEMORY);
  598.       }
  599.    } else {
  600.       TempX=16;
  601.       TempY=height;
  602.       InitRastPort(&MyRast);
  603.       InitBitMap(&MyBm,(long)depth,16L,(long)height);
  604.       for(a=0;a<8;a++) MyBm.Planes[a]=0;
  605.       for(a=0;a<depth;a++) {
  606.          if(!(MyBm.Planes[a]=AllocRaster(16L,(long)height))) return(NO_MEMORY);
  607.       }
  608.    }
  609.    MyRast.BitMap=&MyBm;
  610.    count=ptr=0;
  611.    runlen=1;
  612.    return(0);
  613. }
  614.  
  615. /* uncompress bitplanes */
  616.  
  617. static compget(fp)
  618. FILE *fp;
  619. {
  620.    int c;
  621.    char cc;
  622.    UBYTE val;
  623.    if(ptr>=count) {
  624.       if((c=getc(fp))==EOF) return(EOF);
  625.       cc=c;
  626.       ptr=0;
  627.       if(c==128) {   /* code for copying columns */
  628.          if((c=getc(fp))==EOF) return(EOF);
  629.          count=c+1;  /* count shorts of 256 (value indicating copy mode) */
  630.          for(c=0;c<count;c++) buf[c]=256;
  631.       } else if(cc>=0) {  /* read uncompressed data */
  632.          count=cc+1;
  633.          for(c=0;c<count;c++) if((buf[c]=getc(fp))==EOF) return(EOF);
  634.       } else {
  635.          count=-cc+1;   /* read compressed data and uncompress it */
  636.          if((c=getc(fp))==EOF) return(EOF);
  637.          val=c;
  638.          for(c=0;c<count;c++) buf[c]=val;
  639.       }
  640.    }
  641.    if(ptr>=count) return(EOF);
  642.    return(buf[ptr++]);
  643. }
  644.  
  645.  
  646.